/***************************************************************************
 创建者: hualei
 开始时间: 2018.9.10
 copyright: (C) 深圳市华友高科有限公司
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2018.9.10 类的具体实现代码编写

 ***************************************************************************/
#include "ftpmanage.h"
#include <QDebug>
#include <QTextCodec>

#ifdef D_USE_QT5FTP
#include "../qftp/qftp.h"
#else
#include <QFtp>
#include <QUrlInfo>
#endif

FtpManage::FtpManage(QWidget *parent)
    : QWidget(parent)
{
    #ifdef D_USE_QT5FTP
    #else
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
    #endif
    getDirectoryFlag = false;
    isFtpLoginSuccessed = false;
    ftp=NULL;
    isDownLoadFile=false;

}

FtpManage::~FtpManage()
{

}

bool FtpManage::isDownLoadFileStatus()
{
    return isDownLoadFile;

}

int FtpManage::checkFtpState()
{
    if(NULL==ftp)
    {
        return -1;
    }
    qDebug()<<ftp->state();
    qDebug()<<ftp->error();
    if(QFtp::LoggedIn!=ftp->state())
    {
        ftp->connectToHost(host_last, port_last);
        ftp->login(userName_last, passwd_last);
        return 1;
    }
    return 0;
}

int FtpManage::ftpLogin(const QString &host, int port, const QString &userName, const QString &passwd)
{
    host_last=host;
    port_last=port;
    userName_last=userName;
    passwd_last=passwd;
    if(NULL!=ftp)
    {
        delete ftp;
    }
    ftp = new QFtp(this);
    QObject::connect(ftp, SIGNAL(commandStarted(int)), this, SLOT(ftpCommandStartSlot(int)));
    QObject::connect(ftp, SIGNAL(commandFinished(int,bool)), this, SLOT(ftpCommandFinishSlot(int,bool)));
    QObject::connect(ftp, SIGNAL(dataTransferProgress(qint64,qint64)), this, SLOT(updateDataTransferProgress(qint64,qint64)));
    QObject::connect(ftp, SIGNAL(listInfo(QUrlInfo)), this, SLOT(addToList(QUrlInfo)));
    QObject::connect(ftp, SIGNAL(stateChanged(int)), this, SLOT(stateChangedSlot(int)));
    ftp->connectToHost(host, port);
    ftp->login(userName, passwd);
    return ftp->currentId();
}

int FtpManage::ftpPutFile(const QString &fileName, const QString &clientPath, const QString &serverPath)
{
      checkFtpState();
    QString clientObjPath;
    QString servierObjPath;

    if(clientPath.endsWith("/"))
    {
        clientObjPath = clientPath;
    }
    else
    {
        clientObjPath = clientPath + "/";
    }

    if(serverPath.endsWith("/"))
    {
        servierObjPath = serverPath;
    }
    else
    {
        servierObjPath = serverPath + "/";
    }
    qDebug() << "Put File Client AbsolutePath :" << (clientObjPath + fileName);
    qDebug() << "Put File Server AbsolutePath :" << (servierObjPath + fileName);
    file = new QFile((clientObjPath + fileName));
    if(!file->open(QIODevice::ReadOnly))
    {
        qDebug() << "FTP Put Open File Failed : " << fileName << "The File Path Error!";
        delete file;
        return -1;
    }
    QByteArray data = file->readAll();
    ftp->put(data,_ToSpecialEncoding((servierObjPath + fileName)));
    emit showFtpPutDialog();
    emit currentPutFile(fileName);
    return ftp->currentId();
}

int FtpManage::ftpGetFile(const QString &fileName, const QString &clientAbsolutePath,
                          const QString &serverAbsolutePath)
{
      checkFtpState();
    QString clientPath;
    QString serverPath;

    if(clientAbsolutePath.endsWith("/"))
    {
        clientPath = clientAbsolutePath;
    }
    else
    {
        clientPath = clientAbsolutePath + "/";
    }

    if(serverAbsolutePath.endsWith("/"))
    {
        serverPath = serverAbsolutePath;
    }
    else
    {
        serverPath = serverAbsolutePath + "/";
    }

    file = new QFile((clientPath + fileName));
    qDebug() << "Get FileName :" << file->fileName();
    qDebug() << "Get ServerFileName :" << (serverPath + fileName);
    if(!file->open(QIODevice::WriteOnly))
    {
        qDebug() << "FtpGetFile Open File Failed !";
        delete file;
        file = NULL;
        return -1;
    }
    ftp->get(_ToSpecialEncoding((serverPath + fileName)), file);
    emit showFtpGetDialog();
    emit currentGetFile(fileName);
//    qDebug() << "Get File Client AbsolutePath :" << file->fileName();
//    qDebug() << "Get File Server AbsolutePath :" << (serverPath + fileName);
    return ftp->currentId();
}

int FtpManage::ftpRemoveFile(const QString &fileName, const QString &path)
{
    checkFtpState();
    if(fileName.isEmpty() || path.isEmpty())
    {
        return -1;
    }
    QString removePath;
    qDebug() << "Remove File Path:" << (removePath + fileName);

    if(path.endsWith("/"))
    {
        removePath = path;
    }
    else
    {
        removePath = path + "/";
    }
    ftp->remove(_ToSpecialEncoding((removePath + fileName)));
    return ftp->currentId();
}

int FtpManage::getFileInDirectory(const QString& serverDirectoryPath, const QString& clientPath)
{
   isDownLoadFile=true;
   checkFtpState();
   if(serverDirectoryPath.isEmpty() || clientPath.isEmpty())
   {
       return -1;
   }
   QString serverPath;
   QString clientObjPath;

   if(!(serverDirectoryPath.endsWith("/")))
   {
        serverPath = serverDirectoryPath + "/";
   }
   else
   {
       serverPath = serverDirectoryPath;
   }

   if(!(clientPath.endsWith("/")))
   {
        clientObjPath = clientPath + "/";
   }
   else
   {
       clientObjPath = clientPath;
   }

   ftp->list(serverPath);
   listFtpDirectory = serverPath;
   listGetFileClientPath = clientObjPath;

   return ftp->currentId();
}

void FtpManage::setLoginFileGetFlag(bool status)
{
    loginGetDirFlag = status;
}

void FtpManage::setGetDirFlag(bool status)
{
    getDirectoryFlag = status;
}

bool FtpManage::isGetDir()
{
    return getDirectoryFlag;
}

bool FtpManage::isLoginDirFlag()
{
    return loginGetDirFlag;
}

void FtpManage::ftpCommandStartSlot(int)
{
    int id = ftp->currentCommand();
    switch (id)
    {
        case QFtp::ConnectToHost :
        {
            qDebug() << tr("正在连接到服务器…");
            break;
        }
        case QFtp::Login :
        {
            qDebug() << tr("正在登录…");
            break;
        }
        case QFtp::Get :
        {
            qDebug() << tr("正在下载…");
            break;
        }
        case QFtp::Put :
        {
            qDebug() << tr("正在上传…");
            break;
        }
        case QFtp::List :
        {
            qDebug() << tr("正在查看文件列表…");
            break;
        }
        case QFtp::Close :
        {
            qDebug() << tr("正在关闭连接…");
            break;
        }
    }
}

void FtpManage::ftpCommandFinishSlot(int , bool error)
{
    if(error)
    {
        emit ftpError_signal(ftp->errorString());
    }

    int currentCommandId = ftp->currentCommand();
    switch (currentCommandId)
    {
    case QFtp::ConnectToHost:
    {
        if (error)
        {
            qDebug() << tr("连接服务器出现错误：%1").arg(ftp->errorString());
            emit isConnectToHost(false, ftp->errorString());
        }
        else
        {
            qDebug() << tr("已连接");
            qDebug() << tr("连接到服务器成功");
            emit isConnectToHost(true,tr("连接到服务器成功"));
        }
        break;
    }
    case QFtp::Login:
    {
        if (error)
        {
            qDebug() << tr("ftp登录出现错误：%1").arg(ftp->errorString());
            isFtpLoginSuccessed = false;
            emit isLogined(false, ftp->errorString());
        }
        else
        {
            qDebug() << tr("-------------------ftp登录成功!!!!!!!!!!!!!!");
            isFtpLoginSuccessed = true;
            emit isLogined(true, tr("登录成功"));
        }
        break;
    }
    case QFtp::Get:
    {
        if(error)
        {
            qDebug() << tr("下载出现错误：%1").arg(ftp->errorString());
            emit isGetFile(false, ftp->errorString());
            file->close();
            file->remove();
        }
        else
        {
            file->close();
            emit isGetFile(true, tr("文件下载完成"));
            qDebug() << tr("下载完成");
        }
        break;
    }
    case QFtp::Put:
    {
        if(error)
        {
            qDebug() << tr("上传出现错误:%1").arg(ftp->errorString());
            emit isPutFile(false, ftp->errorString());
        }
        else
        {
            file->close();
            emit isPutFile(true,tr("文件上传成功"));
            qDebug() << tr("文件上传成功");
        }
        break;
    }
    case QFtp::Mkdir:
    {
        if(error)
        {
            qDebug() << tr("创建文件夹失败:%1").arg(ftp->errorString());
        }
        else
        {
            qDebug() << tr("新建文件夹完成");
            //刷新显示列表
            ftp->list();
        }
        break;
    }
    case QFtp::Remove:
    {
        if(error)
        {
            qDebug() << tr("文件删除失败:%1").arg(ftp->errorString());
            emit isRemoveFile(false, ftp->errorString());
        }
        else
        {
            emit isRemoveFile(true, tr("删除完成！"));
            qDebug() << tr("删除完成！");
        }
        break;
    }
    case QFtp::Rmdir:
    {
        if(error)
        {
            qDebug() << tr("文件夹删除失败:%1").arg(ftp->errorString());
        }
        else
        {
            qDebug() << tr("文件夹删除完成！");
            ftp->list();
        }
        break;
    }
    case QFtp::Close:
    {
        qDebug() << tr("已经关闭连接");
    }
    case QFtp::List:
    {
        if(error)
        {
            qDebug() << tr("ftp查看文件列表失败：%1").arg(ftp->errorString());
            emit isGetDirectoryFile(false, ftp->errorString());
//            ftpLogin(host_last,port_last,userName_last,passwd_last);
//            qDebug() << tr("ftp:try to reconnect...");
        }
        else
        {
            qDebug() << tr("ftp文件列表信息获取完毕!");
            emit isGetDirectoryFile(true, tr("文件列表信息获取完毕2!"));
            emit getFileInServerDirectory(isDirectory,listFtpDirectory,listGetFileClientPath);
            //201912255555
            isDirectory.clear();
        }
    }
    default:
        break;
    }
}

void FtpManage::updateDataTransferProgress(qint64 inReadBytes, qint64 toFtpDataBytes)
{
//    qDebug() << "toFtpDataBytes :" << toFtpDataBytes;
//    qDebug() << "inReadBytes :" << inReadBytes;
    emit updateProgress(inReadBytes, toFtpDataBytes);
}

void FtpManage::addToList(const QUrlInfo &urlInfo)
{
    if(_FromSpecialEncoding(urlInfo.name()).startsWith("."))
    {
        return;
    }
    isDirectory[urlInfo.name()] = urlInfo.isDir();
}

void FtpManage::stateChangedSlot(int state)
{
    switch (state)
    {
        case QFtp::Unconnected: {
            qDebug() << tr("没有连接到主机");
            break;
        }
        case QFtp::HostLookup: {
            qDebug() << tr("正在进行主机名查找");
            break;
        }
        case QFtp::Connecting: {
            qDebug() << tr("正在尝试连接到主机");
            break;
        }
        case QFtp::Connected: {
            qDebug() << tr("已实现与主机的连接");
            break;
        }
        case QFtp::LoggedIn: {
            qDebug() << tr("已实现连接和用户登录");
            break;
        }
        case QFtp::Closing: {
            qDebug() << tr("连接正在关闭");
            break;
        }
    default:
        break;
    }
}

bool FtpManage::isFtpLoginSuccess()
{
    return isFtpLoginSuccessed;
}

void FtpManage::getServerFileListInfo(const QString &path)
{
<<<<<<< HEAD
    ftp->list(path);
=======
    if(ftp)
    {
        ftp->list(path);
    }

>>>>>>> dev
}

//有FTP端编码转本地编码
QString FtpManage::_FromSpecialEncoding(const QString &InputStr)
{
#ifdef Q_OS_WIN
    return  QString::fromLocal8Bit(InputStr.toLatin1());
#else
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    if (codec)
    {
        return codec->toUnicode(InputStr.toLatin1());
    }
    else
    {
        return QString("");
    }
#endif
}

//put get等上传文件时，转换为FTP端编码
QString FtpManage::_ToSpecialEncoding(const QString &InputStr)
{
#ifdef Q_OS_WIN
    return QString::fromLatin1(InputStr.toLocal8Bit());
#else
    QTextCodec *codec= QTextCodec::codecForName("gbk");
    if (codec)
    {
        return QString::fromLatin1(codec->fromUnicode(InputStr));
    }
    else
    {
        return QString("");
    }
#endif
}
